package org.sbbs.base.pagequery.hibernate;

import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.impl.CriteriaImpl;
import org.sbbs.base.pagequery.PagedQueryDao;
import org.sbbs.base.pager.IPager;
import org.sbbs.base.pager.SortOrder;
import org.sbbs.base.searcher.SearchFilter;
import org.sbbs.base.utils.TestTimer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Repository;

@Repository("hibernateCriteriaPagedQueryDao")
public class HibernateCriteriaPagedQueryDaoImpl implements PagedQueryDao {
	protected final Log log = LogFactory.getLog(getClass());
	private HibernateTemplate hibernateTemplate;
	private SessionFactory sessionFactory;

	public HibernateCriteriaPagedQueryDaoImpl() {
	}

	public HibernateCriteriaPagedQueryDaoImpl(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
		this.hibernateTemplate = new HibernateTemplate(sessionFactory);
	}

	public HibernateTemplate getHibernateTemplate() {
		return this.hibernateTemplate;
	}

	public SessionFactory getSessionFactory() {
		return this.sessionFactory;
	}

	@Autowired
	@Required
	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
		this.hibernateTemplate = new HibernateTemplate(sessionFactory);
	}

	public IPager pagedQuery(Class clazz, IPager pager,
			SearchFilter searchFilter) throws Exception {
		return this.pagedQuery(clazz, pager, searchFilter, null);
	}

	public IPager pagedQuery(Class clazz, IPager pager,
			SearchFilter searchFilter, CustomCriteria customCriteria)
			throws Exception {
		Session session = this.sessionFactory.openSession();// getCurrentSession();
		// 查询当前页所需记录
		Criteria criteria = null;
		if (customCriteria != null)
			criteria = customCriteria.getCustomCriteria(clazz, session);
		else
			criteria = session.createCriteria(clazz);
		String orderBy = pager.getSortCriterion();
		criteria.setFirstResult(pager.getStart());
		criteria.setMaxResults(pager.getPageSize());
		if (orderBy != null) {
			criteria = CriteriaUtil.createAliasCriteria(
					(CriteriaImpl) criteria, orderBy,
					CriteriaSpecification.LEFT_JOIN);

			if (pager.getSortDirection() == SortOrder.DESCENDING)
				criteria.addOrder(Order.desc(orderBy));
			else
				criteria.addOrder(Order.asc(orderBy));
		}
		if (searchFilter != null)
			criteria = CriteriaUtil.getHibernateCriteria(criteria, clazz,
					searchFilter);// eria(criteria,
		// object);
		// criteria.setCacheable(false);
		// TestTimer tt = new TestTimer("pagedQuery->list");
		// tt.begin();
		List recList = criteria.list();
		// tt.done();
		// 查询总记录数
		int count = 0;
		if (customCriteria != null)
			criteria = customCriteria.getCustomCriteria(clazz, session);
		else
			criteria = session.createCriteria(clazz);
		criteria.setProjection(Projections.rowCount());
		if (this.log.isDebugEnabled())
			log.debug(criteria.toString());
		if (searchFilter != null)
			criteria = CriteriaUtil.getHibernateCriteria(criteria, clazz,
					searchFilter);// eria(criteria,
		// object);
		// tt = new TestTimer("pagedQuery->count");
		// tt.begin();
		List countList = criteria.list();
		// tt.done();
		if (!countList.isEmpty())
			count = ((Long) countList.get(0)).intValue();
		pager.setTotalNumberOfRows(count);
		pager.setList(recList);

		session.close();
		return pager;

	}

}
